﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Script.Serialization;

using Vote.Business;
using Vote.Web.Common;
using Vote.Web.Models;
using Vote.WechatEntity;
using Vote.YouKuEntity;

namespace Vote.Web.Controllers
{
    public class HomeController : Controller
    {
        private const string CACHE_KEY_ACCESSTOKEN = "ACCESS_TOKEN";
        private const string CACHE_KEY_ACTIONID = "ACTION_ID";
        private const string CACHE_KEY_CODE = "WECHAT_CODE";
        private const string CACHE_KEY_VOTELIST = "VOTE_LIST";
        private const string CACHE_KEY_VIDEOIMAGES = "VIDEO_IMAGES";
        private const string CACHE_KEY_USERINFO = "USERINFO";
        private const string CACHE_KEY_USERINFO_KEY = "E8A20C84-6AEC-4C58-9789-A222EBDBE6F8";

        public ActionResult Index(string id)
        {
            // 获取到投票ID
            int actionId = 0;
            int.TryParse(id, out actionId);
            TempData[CACHE_KEY_ACTIONID] = actionId;

            try
            {
                if (Session[CACHE_KEY_USERINFO_KEY] != null)
                {
                    var userInfo = Session[CACHE_KEY_USERINFO_KEY] as UserInfoEntity;
                    if (userInfo != null && !string.IsNullOrWhiteSpace(userInfo.Userid))
                    {
                        // 缓存对象数据
                        TempData[CACHE_KEY_USERINFO] = userInfo;
                        Response.Redirect("Home/Wechat");
                    }
                }
            }
            catch { }

            // 获取AccessToken
            var accessTokenInfo = GetAccessToken();

            // 缓存对象数据
            TempData[CACHE_KEY_ACCESSTOKEN] = accessTokenInfo;

            // 跳转至授权页
            string requestUrl = string.Format("https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect", ConfigUtility.CorpID, ConfigUtility.GetCodeCallBackUrl);

            Response.Redirect(requestUrl);
            return View();
        }

        public ActionResult GetCode()
        {
            // 获取Code
            TempData[CACHE_KEY_CODE] = Request.Params["Code"]; ;
            Response.Redirect(ConfigUtility.RedirectUrl);
            return View();
        }

        // 跳转微信投票页
        public ActionResult WeChat()
        {
            UserInfoEntity userInfo = TempData[CACHE_KEY_USERINFO] as UserInfoEntity;
            //var userInfo = new UserInfoEntity() { Name = "123", Mobile = "1234123", Userid = "xiaoxuan" };

            string userInfoJsonStr = string.Empty;
            if (userInfo == null || string.IsNullOrWhiteSpace(userInfo.Userid))
            {
                // 获取用户信息
                userInfo = GetUserInfo();
                // 缓存用户信息
                Session[CACHE_KEY_USERINFO_KEY] = userInfo;
            }

            if (userInfo == null)
            {
                Response.Write("<script language=\"javascript\">window.opener=null;window.close();</script>");
                return View();
                throw new Exception("获取用户信息失败，请重试！");
            }

            userInfoJsonStr = JsonConvert.SerializeObject(userInfo);
            var actionId = TempData[CACHE_KEY_ACTIONID];
            // 判读投票状态(1进行中/2已完成/3已过期)
            var votingConfig = UserVoteModel.Instance.GetUserVoteStatus(Convert.ToInt32(actionId), userInfo.Userid);
            if (votingConfig == null) { actionId = -1; }
            var actionInfo = (votingConfig != null) ? votingConfig.Item2 : null;

            var data = new
             {
                 ActionID = actionId,
                 ActionInfo = JsonConvert.SerializeObject(actionInfo.ConvertToViewModel3()),
                 UserInfo = userInfoJsonStr,
                 VotingStatus = votingConfig != null ? votingConfig.Item1 : -1,
                 VoteBeginTime = votingConfig != null ? actionInfo.BeginTime.ToString("yyyy-MM-dd HH:mm") : "",
                 IsNotEmployee = (userInfo == null || string.IsNullOrWhiteSpace(userInfo.Userid))
             };

            ViewBag.ActionConfig = new JavaScriptSerializer().Serialize(data);

            return View();
        }


        // 获取投票状态
        public JsonResult GetVoteStatus(string actionId, string userId)
        {
            int intActionID = 0;
            int.TryParse(actionId, out intActionID);

            // 判读投票状态(1进行中/2已完成/3已过期)
            var votingConfig = UserVoteModel.Instance.GetUserVoteStatus(Convert.ToInt32(actionId), userId);
            int votingStatus = votingConfig.Item1;

            return new JsonResult() { Data = new { VotingStatus = votingStatus }, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }

        // 获取投票信息
        public JsonResult GetVoteInfo(string actionId)
        {
            int intActionID = 0;
            int.TryParse(actionId, out intActionID);

            List<VoteViewModel> votingList = new List<VoteViewModel>();
            votingList = HttpRuntime.Cache[CACHE_KEY_VOTELIST + actionId] as List<VoteViewModel>;
            if (votingList == null)
            {
                // 获取投票列表
                var voteActionModel = VoteModel.Instance.GetVoteActionByActionID(intActionID);
                votingList = (voteActionModel.VoteList ?? new List<GroupEntity>()).ConvertAll(V => V.ConverToViewModel());
                try
                {
                    // 加入缓存
                    HttpRuntime.Cache.Insert(CACHE_KEY_VOTELIST + actionId, votingList, null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromSeconds(3600));
                }
                catch { }
            }

            var videoVideoList = votingList.Where(V => V.VoteType == 2).ToList();
            if (videoVideoList.Count > 0)
            {
                GetVideoList(videoVideoList);
            }

            return new JsonResult() { Data = new { VotingList = votingList }, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }

        // 保存投票信息
        [HttpPost]
        public ActionResult SaveVotingResult(UserVoteInfoViewModel userVoteInfo)
        {
            bool isVoted = UserVoteModel.Instance.IsVoted(Convert.ToInt32(userVoteInfo.ActionID), userVoteInfo.UserInfo.Userid);
            int retcode = -1;
            if (!isVoted)
            {
                List<int> selectedVoteItem = new List<int>();
                if (userVoteInfo.SelectedOptions != null && userVoteInfo.SelectedOptions.Count > 0)
                {
                    selectedVoteItem.AddRange(userVoteInfo.SelectedOptions.ConvertAll(O => Convert.ToInt32(O)));
                }

                retcode = UserVoteModel.Instance.SaveVotingResult(Convert.ToInt32(userVoteInfo.ActionID), userVoteInfo.UserInfo.Userid, selectedVoteItem);
            }
            return new JsonResult() { Data = new { RetCode = retcode }, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }


        public ActionResult Video(string videoId)
        {
            ViewBag.VideoID = videoId;
            return View();
        }

        #region Private Mothod
        // 获取视频列表
        private void GetVideoList(List<VoteViewModel> votingList)
        {
            var videoIdList = new List<string>();
            foreach (var vote in votingList)
            {
                videoIdList.AddRange((from item in vote.VoteItemList select item.RelationVideo).Distinct().ToList());
            }
            videoIdList.RemoveAll(O => (O == null || string.IsNullOrWhiteSpace(O)));


            // 读取缓存
            var videoDict = new Dictionary<string, VideoEntity>();
            videoDict = (HttpRuntime.Cache[CACHE_KEY_VIDEOIMAGES] as Dictionary<string, VideoEntity> ?? new Dictionary<string, VideoEntity>());

            // 删除已经在缓存里的视频ID
            videoIdList.RemoveAll(O => videoDict.ContainsKey(O));

            // 调用YoukuAPI获取视频截图
            var videoInfo = this.GetVideoInfo(videoIdList);

            #region 缓存视频图片
            try
            {
                if (videoInfo.Count > 0)
                {
                    foreach (var video in videoInfo)
                    {
                        if (!videoDict.ContainsKey(video.Id))
                        {
                            videoDict.Add(video.Id, video);
                        }
                        else
                        {
                            videoDict[video.Id] = video;
                        }
                    }
                    HttpRuntime.Cache.Insert(CACHE_KEY_VIDEOIMAGES, videoDict, null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromSeconds(3600));
                }
            }
            catch { }
            #endregion

            foreach (var vote in votingList)
            {
                foreach (var item in vote.VoteItemList)
                {
                    // 优先读取缓存
                    var cacheVideo = (!string.IsNullOrWhiteSpace(item.RelationVideo) && videoDict.ContainsKey(item.RelationVideo)) ? videoDict[item.RelationVideo] : null;

                    if (cacheVideo != null && !string.IsNullOrWhiteSpace(cacheVideo.BigThumbnail))
                    {
                        item.ImageUrl = cacheVideo.BigThumbnail;
                    }
                }
            }
        }


        // 获取AccessTokens
        private AccessTokenEntity GetAccessToken()
        {
            string requestUrl = string.Format("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={0}&corpsecret={1}", ConfigUtility.CorpID, ConfigUtility.CorpSecret);

            CookieCollection cookies = new CookieCollection();//如何从response.Headers["Set-Cookie"];中获取并设置CookieCollection的代码略
            var response = HttpWebResponseUtility.CreateGetHttpResponse(requestUrl, null, null, cookies);

            string responJsonStr = string.Empty;
            using (Stream myResponseStream = response.GetResponseStream())
            {
                using (StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8")))
                {
                    responJsonStr = myStreamReader.ReadToEnd();
                }
            }

            try
            {
                var accessTokenInfo = new JavaScriptSerializer().Deserialize<AccessTokenEntity>(responJsonStr);
                return accessTokenInfo;
            }
            catch (Exception ex)
            { throw new Exception(ex.Message + responJsonStr); }
        }

        // 获取UID
        private string GetUID(string accesstoken, string code)
        {
            if (string.IsNullOrWhiteSpace(code)) { return string.Empty; }
            string requestUrl = string.Format("https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token={0}&code={1}&agentid={2}", accesstoken, code, ConfigUtility.AgentID);

            CookieCollection cookies = new CookieCollection();//如何从response.Headers["Set-Cookie"];中获取并设置CookieCollection的代码略
            var response = HttpWebResponseUtility.CreateGetHttpResponse(requestUrl, null, null, cookies);

            string responJsonStr = string.Empty;
            using (Stream myResponseStream = response.GetResponseStream())
            {
                using (StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8")))
                {
                    responJsonStr = myStreamReader.ReadToEnd();
                }
            }

            try
            {
                var uidInfo = new JavaScriptSerializer().Deserialize<UIDEntity>(responJsonStr);
                return uidInfo.UserId;
            }
            catch (Exception ex)
            { throw new Exception(ex.Message + responJsonStr); }

        }

        private UserInfoEntity GetUserInfo()
        {
            // 获取Token
            var accessTokenInfo = TempData[CACHE_KEY_ACCESSTOKEN] as AccessTokenEntity;
            var accessToken = (accessTokenInfo != null) ? accessTokenInfo.Access_Token : GetAccessToken().Access_Token;

            // 获取Code
            var code = TempData[CACHE_KEY_CODE] as string;

            // 获取用户UID
            var uid = GetUID(accessToken, code);

            // 获取用户信息
            var userInfo = GetUserInfoByUID(accessToken, uid);

            // 优先选择工号，若没工号用账号
            SetUserID(userInfo);

            return userInfo;
        }


        // 获取用户信息
        private UserInfoEntity GetUserInfoByUID(string accesstoken, string uid)
        {
            string requestUrl = string.Format("https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token={0}&userid={1}", accesstoken, uid);

            CookieCollection cookies = new CookieCollection();//如何从response.Headers["Set-Cookie"];中获取并设置CookieCollection的代码略
            var response = HttpWebResponseUtility.CreateGetHttpResponse(requestUrl, null, null, cookies);

            string responJsonStr = string.Empty;
            using (Stream myResponseStream = response.GetResponseStream())
            {
                using (StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8")))
                {
                    responJsonStr = myStreamReader.ReadToEnd();
                }
            }

            try
            {
                var userInfo = new JavaScriptSerializer().Deserialize<UserInfoEntity>(responJsonStr);
                return userInfo;
            }
            catch (Exception ex)
            { throw new Exception(ex.Message + responJsonStr); }
        }

        private void SetUserID(UserInfoEntity userInfo)
        {
            if (userInfo == null) { return; }
            string newUserID = userInfo.Userid;
            if (userInfo.Extattr != null && userInfo.Extattr.Attrs != null)
            {
                var info = userInfo.Extattr.Attrs.Where(O => O.Name == "工号").FirstOrDefault();
                if (info != null && !string.IsNullOrWhiteSpace(info.Value))
                {
                    userInfo.Userid = info.Value;
                }
            }
        }

        // 获取用户信息
        //  网站链接 http://v.youku.com/v_show/id_XOTU5Mjg5NzEy.html?f=23805495&from=y1.2-3.4.20
        private List<VideoEntity> GetVideoInfo(List<string> videoIdList)
        {
            if (videoIdList == null || videoIdList.Count == 0) { return new List<VideoEntity>(); }
            string videoIdListStr = string.Join(",", videoIdList);
            string requestUrl = string.Format("https://openapi.youku.com/v2/videos/show_batch.json?client_id={0}&video_ids={1}", ConfigUtility.YoukuClientId, videoIdListStr);

            var response = HttpWebResponseUtility.CreateGetHttpResponse(requestUrl, null, null, new CookieCollection());

            string responJsonStr = string.Empty;
            using (Stream myResponseStream = response.GetResponseStream())
            {
                using (StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8")))
                {
                    responJsonStr = myStreamReader.ReadToEnd();
                }
            }

            try
            {
                var videoInfo = new JavaScriptSerializer().Deserialize<VidoListEntity>(responJsonStr);
                return (videoInfo != null && videoInfo.Total > 0) ? videoInfo.Videos : new List<VideoEntity>();
            }
            catch (Exception ex)
            { throw new Exception(ex.Message + responJsonStr); }
        }

        #endregion

    }
}
